﻿using System.Collections.Generic;
using System.Windows;
using Newtonsoft.Json;
using Saber.Infrastructure.Http;

namespace Saber.Plugin.Youdao
{
    public class TranslateResult
    {
        public int errorCode { get; set; }
        public List<string> translation { get; set; }
        public BasicTranslation basic { get; set; }
        public List<WebTranslation> web { get; set; }
    }

    // 有道词典-基本词典
    public class BasicTranslation
    {
        public string phonetic { get; set; }
        public List<string> explains { get; set; }
    }

    public class WebTranslation
    {
        public string key { get; set; }
        public List<string> value { get; set; }
    }

    public class Main : IPlugin
    {
        private PluginInitContext _context;

        private static PluginMetadata metadata;

        static Main()
        {
            metadata = new PluginMetadata();
            metadata.ID = "095A6AE3A254432EBBD78F05A71D4981";
            metadata.Name = "有道翻译";
            metadata.Description = "有道中英互译";
            metadata.ActionKeyword = "yd";
            metadata.IcoPath = "Images\\youdao.ico";

        }


        public List<Result> Query(Query query)
        {
            List<Result> results = new List<Result>();
            const string ico = "Images\\youdao.ico";
            if (query.Search.Length == 0)
            {
                results.Add(new Result
                {
                    Title = "开始有道中英互译",
                    SubTitle = "基于有道网页接口 http://aidemo.youdao.com/trans",
                    IcoPath = ico
                });
                return results;
            }

            Dictionary<string,string> dic = new Dictionary<string, string>();
            dic.Add("from", "auto");
            dic.Add("to", "auto");
            dic.Add("q", query.Search);
            var json = Http.Post("http://aidemo.youdao.com/trans", dic).Result;
            TranslateResult o = JsonConvert.DeserializeObject<TranslateResult>(json);
            if (o.errorCode == 0)
            {

                if(o.translation != null)
                {
                    var translation = string.Join(", ", o.translation.ToArray());
                    var title = translation;
                    if (o.basic?.phonetic != null)
                    {
                        title += " [" + o.basic.phonetic + "]";
                    }
                    results.Add(new Result
                    {
                        Title = title,
                        SubTitle = "翻译结果",
                        IcoPath = ico,
                        Action = this.copyToClipboardFunc(translation)
                    });
                }

                if(o.basic?.explains != null)
                {
                    var explantion = string.Join(",", o.basic.explains.ToArray());
                    results.Add(new Result
                    {
                        Title = explantion,
                        SubTitle = "简明释义",
                        IcoPath = ico,
                        Action = this.copyToClipboardFunc(explantion)
                    });
                }

                if (o.web != null)
                {
                    foreach (WebTranslation t in o.web)
                    {
                        var translation = string.Join(",", t.value.ToArray());
                        results.Add(new Result
                        {
                            Title = translation,
                            SubTitle = "网络释义："+ t.key,
                            IcoPath = ico,
                            Action = this.copyToClipboardFunc(translation)
                        });
                    }
                }
            }
            else
            {
                string error = string.Empty;
                switch (o.errorCode)
                {
                    case 101: error = "缺少必填的参数，出现这个情况还可能是et的值和实际加密方式不对应"; break;
                    case 102: error = "不支持的语言类型"; break;
                    case 103: error = "翻译文本过长"; break;
                    case 104: error = "不支持的API类型"; break;
                    case 105: error = "不支持的签名类型"; break;
                    case 106: error = "不支持的响应类型"; break;
                    case 107: error = "不支持的传输加密类型"; break;
                    case 108: error = "appKey无效，注册账号，登录后台创建应用和实例并完成绑定，可获得应用ID和密钥等信息，其中应用ID就是appKey（注意不是应用密钥）"; break;
                    case 109: error = "batchLog格式不正确"; break;
                    case 110: error = "无相关服务的有效实例"; break;
                    case 111: error = "开发者账号无效"; break;
                    case 113: error = "q不能为空"; break;
                    case 201: error = "解密失败，可能为DES,BASE64,URLDecode的错误"; break;
                    case 202: error = "签名检验失败"; break;
                    case 203: error = "访问IP地址不在可访问IP列表"; break;
                    case 205: error = "请求的接口与选择的接入方式不一致"; break;
                    case 301: error = "辞典查询失败"; break;
                    case 302: error = "翻译查询失败"; break;
                    case 303: error = "服务端的其它异常"; break;
                    case 401: error = "账户已经欠费"; break;
                    case 411: error = "访问频率受限,请稍后访问"; break;
                    case 2005: error = "ext参数不对"; break;
                    case 2006: error = "不支持的voice"; break;
                    default: error = string.Format("%d", o.errorCode); break;
                }

                results.Add(new Result
                {
                    Title = error,
                    IcoPath = ico
                });
            }

            return results;
        }

        public void Init(PluginInitContext context)
        {
            _context = context;
        }

        private System.Func<ActionContext, bool> copyToClipboardFunc(string text)
        {
            return c =>
            {
                if (this.copyToClipboard(text))
                {
                    _context.API.ShowMsg("翻译已被存入剪贴板");
                }
                else
                {
                    _context.API.ShowMsg("剪贴板打开失败，请稍后再试");
                }
                return false;
            };
        }

        private bool copyToClipboard(string text)
        {
            try
            {
                Clipboard.SetText(text);
            }catch(System.Exception e)
            {
                return false;
            }
            return true;
        }

        public PluginMetadata Metadata()
        {
            return metadata;
        }
    }
}
